Skip to content

ci: add integration job and tests for acme-commerce-lenders - #20

Open
localstack-platform[bot] wants to merge 9 commits into
mainfrom
localstack/init-proj_5f62a1e8
Open

localstack-platform[bot] wants to merge 9 commits into
mainfrom
localstack/init-proj_5f62a1e8

Conversation

@localstack-platform

@localstack-platform localstack-platform Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Motivation

The acme-commerce-lenders demo had no test that drives the whole flow against real app emulators. This adds an integration job to CI and Go integration tests, so the docs and the emulators can't drift apart.

Changes

  • .github/workflows/ci.yml: new integration job. It authenticates to the LocalStack platform through GitHub OIDC (no repository secret needed), starts the project with lstk project start, and runs the tests. Fork PRs skip the job because they don't get an OIDC token.
  • demos/acme-commerce-lenders/integration/integration_test.go: a full seed, apply, accept, fund and settle run over HTTP. It also checks the 409 on out-of-order steps and asserts the documented numbers.
  • The tests reset every app emulator they talk to, so they refuse to run unless INTEGRATION_ALLOW_RESET=1 is set. CI sets it.
  • Stripe, plaid and xero all answer 404 on the sandbox LocalStack today, so the job builds them from WonderTwin, pinned to a commit through WONDERTWIN_REF, and starts them without the LocalStack token. LocalStack is started but not exercised, so this is not LocalStack-hosted coverage yet.

Tests

cd demos/acme-commerce-lenders
INTEGRATION_ALLOW_RESET=1 go test -tags integration -count=1 -v ./integration

All three CI jobs (build-and-test, web, integration) are green on cabf9c4: https://github.com/localstack-samples/localstack-app-emulators/actions/runs/42910568236

Related

Removal conditions for the workaround and probe steps are tracked in #24: plaid and xero released in LocalStack, and a sandbox image new enough to serve stripe.

🤖 Generated with Claude Code

@localstack-platform

localstack-platform Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Author

LocalStack PR Review — 🟢 GREEN

Reviewed the pull request which adds a LocalStack CI workflow (integration job in .github/workflows/ci.yml) and Go integration tests (demos/acme-commerce-lenders/integration/integration_test.go). Verified that no AWS infrastructure resources are created or modified by this change and the sandbox remains in a clean state.

Checks · 1 passed · 0 failed · 0 errored

Check Result Expectation
verify_no_aws_resources_created ✅ passed No AWS resources are created by this PR as it only updates CI workflow and integration test files.

✓ No infrastructure changes

✅ passed · Run #58 · localstack/init-proj_5f62a1e8 → main @ 863d829 · vs previous localstack/init-proj_5f62a1e8 run (no successful main baseline yet)

Cost

Fixed monthly, on-demand, USD · - · AWS prices of 2026-11-01

Fixed monthly cost: $0.00/month. No priced base yet: the next default-branch run sets one.

View run in LocalStack · Open sandbox · updated for 863d829 at 2026-11-10T22:04:06Z

The generated localstack-ci.yml becomes an integration job in ci.yml, with
the same pinned actions and fork guard. The job drives the demo over HTTP
against LocalStack: seed facts, the full apply to settle flow, out of order
steps, recorded vendor calls and reset.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@localstack-platform

Copy link
Copy Markdown
Author

LocalStack PR Review — why this CI run failed

LocalStack start failed: Omission of stripe from the app emulator fallback loop · confidence medium (no known signature matched; the agent's diagnosis has verified evidence)

The CI workflow failed during emulator readiness verification because .github/workflows/ci.yml omitted stripe from the loop that checks and runs fallback app emulators (for app in plaid xero; do). Because the LocalStack instance did not include a hosted Stripe emulator, kit ready failed with an error indicating that stripe was not ready and STRIPE_EMULATOR_URL was not set. Adding stripe to the list ensures twin-stripe is built and started via WonderTwin when LocalStack does not host it.

Evidence

github  L351  2026-11-09T21:54:27.1613963Z error: 1 of 3 app emulators are not ready
github  L352  2026-11-09T21:54:27.1614593Z   stripe  localstack not-included  http://127.0.0.1:4566
github  L353  2026-11-09T21:54:27.1615774Z           this LocalStack release does not include stripe. Run it yourself and set STRIPE_EMULATOR_URL.
pr  L112  +          for app in plaid xero; do

What to change

  1. Update the app emulator check loop in .github/workflows/ci.yml to include stripe alongside plaid and xero: for app in stripe plaid xero; do. (.github/workflows/ci.yml)

Diagnosed for d177393 at 2026-11-09 21:55 UTC by google/gemini-3.5-flash on LocalStack's key · open the run · re-run the diagnosis

whummer and others added 2 commits November 9, 2026 23:00
Drops the WonderTwin fallback and the custom port. The job now fails at
the ready check if LocalStack does not host an app emulator.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The test starts the demo in-process, so the job no longer builds the kit,
runs it in the background or polls for it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@localstack-platform

localstack-platform Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Author

LocalStack PR Review — why this CI run failed

LocalStack start failed: Tests failed · confidence high (matched a known signature; the agent agrees)

The integration test suite failed during the test stage because the required vendor app emulators (Stripe, Plaid, and Xero) were not reachable or included in the sandbox environment. When TestSeededWorldIsReadyAndMatchesTheDocs called /api/reset, requests routed to *.localhost.localstack.cloud:4566 returned S3 NoSuchBucket 404 errors, causing the test suite to receive 502 response codes and fail.

Evidence

github  L287  2026-11-10T00:27:32.0471102Z <Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><RequestId>ef4fa377-f9d9-490f-80a2-8867e0dcd345</RequestId><BucketName>admin</BucketName></Error> HTTP 404
github  L294  2026-11-10T00:27:32.5508853Z ##[group]Run go test -tags integration -count=1 -v ./integration
github  L310  2026-11-10T00:27:51.5137115Z     integration_test.go:117: reset: status 502: not ready to seed:
github  L311  2026-11-10T00:27:51.5139495Z         stripe (localstack) is not-included: this LocalStack release does not include stripe. Run it yourself and set STRIPE_EMULATOR_URL.
github  L312  2026-11-10T00:27:51.5141910Z         plaid (localstack) is not-included: this LocalStack release does not include plaid. Run it yourself and set PLAID_EMULATOR_URL.
github  L313  2026-11-10T00:27:51.5143946Z         xero (localstack) is not-included: this LocalStack release does not include xero. Run it yourself and set XERO_EMULATOR_URL.
github  L314  2026-11-10T00:27:51.5145062Z --- FAIL: TestSeededWorldIsReadyAndMatchesTheDocs (1.44s)
github  L342  2026-11-10T00:27:57.3948454Z ##[error]Process completed with exit code 1.

What to change

  1. Configure the LocalStack project runtime environment to enable and load the Stripe, Plaid, and Xero app emulators. (.github/workflows/ci.yml)
  2. Set environment variables (STRIPE_EMULATOR_URL, PLAID_EMULATOR_URL, and XERO_EMULATOR_URL) in .github/workflows/ci.yml if pointing to custom emulator endpoints. (.github/workflows/ci.yml)

Diagnosed for ab1277f at 2026-11-10 00:28 UTC by google/gemini-3.5-flash on LocalStack's key · open the run · re-run the diagnosis

whummer and others added 3 commits November 9, 2026 23:06
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@whummer

whummer commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Heads up: the "Run the app emulators LocalStack does not host" step in the integration job is a temporary workaround, and we should remove it as soon as we can.

Why it's there: the hosted LocalStack sandbox doesn't serve all the emulators the demo needs.

  • plaid and xero aren't in any LocalStack release. The plugins exist on the apps/plaid-ca9fea68d873 and apps/xero-b24aeed25cff branches in localstack-ext, but they aren't merged to main yet.
  • stripe is in current LocalStack, but the sandbox runs an older image (2026.8.4), so it isn't served there either.

So for now the step builds whichever of stripe, plaid and xero LocalStack doesn't answer for from WonderTwin and points the demo at them via <APP>_EMULATOR_URL.

Remove it once:

  1. plaid and xero are merged into localstack-ext main and shipped in a release (or whatever image the sandbox uses), and
  2. the sandbox image is new enough to serve stripe.

The step checks each vendor on LocalStack first and only builds the ones that don't answer, so it will quietly stop doing anything once LocalStack covers them. It is still extra build time and a dependency on the WonderTwin repo, so it should go rather than stay forever.

The "Probe the app emulators" step above it is a debugging aid and can go at the same time.

@tela

tela commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Thanks for this, @whummer . The tests are the valuable part: a full
apply -> settle run over HTTP, the 409 on out-of-order steps, and the
documented numbers asserted so docs and emulators can't drift apart. The
pinned action SHAs and the fork guard are right too.

Four things I'd like in before merge (details inline):

  1. The PR description doesn't match the diff.
  2. The auth token is inherited by binaries built from unpinned WonderTwin code.
  3. CI turns red whenever WonderTwin main changes. Same fix as 2.
  4. Running the integration tests locally wipes your LocalStack.

Items 2 and 3 are one change. Everything else can be a follow-up.

@tela tela left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the description: it says this adds .github/workflows/localstack-ci.yml, lists "Emulator: AWS" and "Tests: none", and asks for a LOCALSTACK_AUTH_TOKEN repo secret. The diff edits ci.yml, adds integration_test.go, and authenticates through OIDC, so no secret is needed. Someone following the checklist would add one for nothing.

Could you rewrite it in the Motivation / Changes / Tests / Related format? Tests should show the exact go test -tags integration command and the green run. Related should carry the removal conditions from your comment. A title like "ci: add integration job and tests for acme-commerce-lenders" would fit.

Side note: the bot's "GREEN" review only checks an STS call, which says nothing about this demo. Worth ignoring as a signal.

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +225 to +229
git clone --depth 1 https://github.com/WonderTwin-AI/wondertwin "$RUNNER_TEMP/wondertwin"
port=5101
for app in $missing; do
(cd "$RUNNER_TEMP/wondertwin" && go build -o "$RUNNER_TEMP/twin-$app" "./twin-$app/cmd/twin-$app")
"$RUNNER_TEMP/twin-$app" --port=$port > "$RUNNER_TEMP/twin-$app.log" 2>&1 &

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two changes here.

Token: the OIDC step puts LOCALSTACK_AUTH_TOKEN in GITHUB_ENV, so every twin started below inherits it, and they are built from whatever WonderTwin main is at run time. They never need the token. Please start them as:

env -u LOCALSTACK_AUTH_TOKEN "$RUNNER_TEMP/twin-$app" --port=$port ...

Pin: git clone --depth 1 takes the default branch, so any WonderTwin change can turn this repo's CI red, and the test asserts exact numbers (941 orders, 8108384 gross, ...). Please pin to a commit. For example, set WONDERTWIN_REF at the top of the job and fetch that SHA. WonderTwin main at the time of the green run was 8f1b30f (inferred from the run time, the log does not record it). Bump it deliberately, in the PR that changes any asserted numbers.


func TestMain(m *testing.M) { os.Exit(run(m)) }

func run(m *testing.M) int {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every test here calls resetWorld, which wipes the app emulators. The package comment says "run lstk, then go test -tags integration". Run locally, that wipes everything in LocalStack's shared Stripe emulator, and in any Plaid or Xero emulator at _EMULATOR_URL.

Please add a guard at the top of run():

if os.Getenv("INTEGRATION_ALLOW_RESET") != "1" {
    fmt.Fprintln(os.Stderr, "this resets every app emulator it talks to; set INTEGRATION_ALLOW_RESET=1 to run")
    return 1
}

Then set it on the go test step in ci.yml and mention it in the package comment.

Comment thread .github/workflows/ci.yml
# localstack-project-id: proj_5f62a1e8 (https://v2.app.localstack.cloud/projects/proj_5f62a1e8)
# Runtime config (emulator image, env vars, extensions) is fetched by
# `lstk project start` at run time, so change it on the platform, not here.
integration:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three smaller things, none blocking:

  • In the run log stripe, plaid and xero all answer 404 on LocalStack, so today all three come from WonderTwin builds and LocalStack is started but not exercised. Could the job comment say that, so nobody reads this as LocalStack-hosted coverage?
  • Please open a tracking issue for removing the workaround step and the probe step, with your two conditions as the checklist (plaid and xero released in LocalStack, sandbox image new enough to serve stripe).
  • 8 commits, several of them CI debugging. Fine to squash-merge into one. Separately: the lstk install is unpinned and the wheel comes from the localstack-artifacts-internal bucket with no hash, in a public repo. Worth confirming with the platform team that this is intended.

- Pin WonderTwin to a commit instead of cloning main, so upstream changes
  cannot turn this repo's CI red.
- Start the twins without LOCALSTACK_AUTH_TOKEN.
- Require INTEGRATION_ALLOW_RESET=1 to run the integration tests, since
  they reset every app emulator they talk to.
- Note in the job comment that all three emulators come from WonderTwin today.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@whummer
whummer requested a review from tela November 10, 2026 22:07
@whummer whummer changed the title Add LocalStack CI workflow (localstack-app-emulators) ci: add integration job and tests for acme-commerce-lenders Nov 12, 2026
@whummer

whummer commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Thanks for the thorough review, @tela. Pushed cabf9c4 with these changes:

  1. Token and pin (ci.yml): The twins now start with env -u LOCALSTACK_AUTH_TOKEN, so they no longer inherit the token. WonderTwin is pinned through WONDERTWIN_REF at the top of the job (8f1b30fcaf8d9f7c97278eff1b29ff476e8eaa26), and the step fetches that exact commit instead of cloning main. It's the last code change before the green run, and the only commit after it is docs-only. The comment above the variable says to bump it in the PR that changes the asserted numbers.
  2. Reset guard (integration_test.go): run() now exits with your message unless INTEGRATION_ALLOW_RESET=1 is set. The go test step in ci.yml sets it, and the package comment documents it and what gets reset.
  3. Job comment: It now says stripe, plaid and xero all come from the WonderTwin builds today, so LocalStack is started but not exercised and this isn't LocalStack-hosted coverage.
  4. PR description: Rewritten in the Motivation / Changes / Tests / Related format, with a new title. Related links the removal conditions.
  5. Tracking issue: Opened ci: remove the WonderTwin workaround and probe steps from the integration job #24 for removing the workaround and probe steps, with the two conditions as the checklist.
  6. Squash and lstk install: Fine with squash-merging. I'll check with the platform team whether the unpinned lstk and the internal-bucket wheel are intended.

CI is green on cabf9c4 (build-and-test, web, integration), so the pinned WonderTwin commit builds and passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants